<template>
  <e-preview-box :title="title" :class="{'img-upload': !$slots.default,'img-upload-value': !$slots.default&&value}" v-loading="loading">
    <button v-if="!$slots.default" type="button">
      <img v-if="value" :src="value" class="avatar">
      <i v-else class="el-icon-plus"></i>
    </button>
    <upload
      v-if="isCrop"
      ref="upload"
      :action="action"
      :auto-upload="false"
      :before-upload="handleBeforeUpload"
      :on-progress="handleProgress"
      :on-success="handleSuccess"
      :on-error="handleError"
      :on-change="handleChange"
      :multiple="false"
       >  
        <slot v-if="$slots.default"></slot>
        <button type="button" class="img-upload-value-button" t v-if="!$slots.default&&value">
          <i class="el-icon-upload"></i>上传图片
        </button>
    </upload>
    <upload
      v-else
      ref="upload"
      v-bind="$props"
      :before-upload="handleBeforeUpload"
      :on-progress="handleProgress"
      :on-success="handleSuccess"
      :on-error="handleError"
      :on-change="handleChange"
       >  
        <slot v-if="$slots.default"></slot>
        <button type="button" class="img-upload-value-button" t v-if="!$slots.default&&value">
          <i class="el-icon-upload"></i>上传图片
        </button>
    </upload>
  </e-preview-box>
</template>

<script>
  import emitter from 'utils/emitter.js'
  import Upload from 'element-ui/lib/upload'
  import Cropper from './Cropper'
  import Vue from 'vue'
  let props = {...Upload.props}
  delete props.onSuccess
  delete props.beforeUpload
  delete props.onProgress
  delete props.onError
  export default {
    componentName: 'EImgUpload',
    mixins: [emitter],
    components: {
      Upload
    },
    props: {
      ...props,
      value: {
        type: String
      },
      showFileList: {
        type: Boolean,
        default: false
      },
      headers: {
        type: Object,
        default () {
          return {}
        }
      },
      accept: {
        type: String,
        default: 'image/jpeg,image/png'
      },
      size: {
        type: Number,
        default: 1024 * 1024 * 5
      },
      validateEvent: {
        type: Boolean,
        default: true
      },
      formatList: {
        type: Array,
        default () {
          return ['.png', '.jpeg', '.jpg']
        }
      },
      action: {
        required: false,
        default: '/api/upload/image'
      },
      isCrop: {
        type: Boolean,
        default: false
      },
      cropProps: {
        type: Object
      }
    },
    data () {
      return {
        loading: false,
        title: document.all ? '可能要双击才能选择文件' : ''
      }
    },
    methods: {
      handleChange (file, fileList) {
        if (navigator.userAgent.indexOf('MSIE 9') > -1) {
          if (this.$message) {
            this.$message({
              message: 'IE 9不支持图片裁剪，请升级更高版本的浏览器',
              type: 'warning'
            })
          }
        } else {
          let self = this
          self.$refs.upload.clearFiles()
          if (!self.$$cropper) {
            let node = document.createElement('div')
            document.body.appendChild(node)
            self.$$cropper = new Vue({ // eslint-disable-line
              el: node,
              components: {
                Cropper
              },
              data () {
                return {
                  src: file.url,
                  visible: true
                }
              },
              render (createElement) {
                return createElement('cropper', {
                  props: {
                    ...self.cropProps,
                    src: this.src,
                    visible: this.visible
                  },
                  on: {
                    submit: this.handleSubmit,
                    upload: this.handleUpload,
                    close: this.handleClose
                  },
                  ref: 'cropper'
                })
              },
              methods: {
                handleSubmit (image) {
                  this.visible = false
                  self.$$cropper = null
                  self.uploadCropImage(image)
                },
                handleUpload () {
                  self.$el.querySelector('.el-upload').click()
                },
                handleClose () {
                  this.visible = false
                  self.$$cropper = null
                  this.$nextTick(this.$destroy)
                }
              }
            })
          } else {
            this.$$cropper.src = file.url
          }
        }
      },
      uploadCropImage (image) {
        this.handleSuccess({
          result: '0',
          data: {
            url: image
          }
        })
      },
      handleBeforeUpload (file) {
        let formatReg = new RegExp(this.formatList.join('|'), 'i')
        if (file.size > this.size) {
          this.$message.error(`上传的文件不能超过${this.size / 1024 / 1024}M`)
          return false
        }
        if (!formatReg.test(file.name)) {
          this.$message.error('图片格式格式不正确,请重新上传')
          return false
        }
        if (this.disabled) {
          return false
        }
        return this.autoUpload
      },
      handleProgress () {
        this.loading = true
      },
      handleSuccess (res) {
        this.loading = false
        if (res.result === '0') {
          let url = res.data.url
          this.$emit('input', url).$emit('change', res.data).$emit('success', url).$emit('blur')
          if (this.validateEvent) { // 触发表单校验
            this.dispatch('ElFormItem', 'el.form.change', [url])
            this.dispatch('ElFormItem', 'el.form.blur', [url])
          }
        } else {
          this.$emit('exception', res)
          this.$message.error(res.msg || '文件上传失败')
        }
      },
      handleError (err, file, fileList) { //eslint-disable-line
        this.$message.error(`"${file.name}"文件上传失败`)
        this.loading = false
      }
    }
  }
</script>
